WebGNSS Client

Versione documentata: 1.3.77 · Interfaccia: http://localhost:8088 · API: http://localhost:8001/docs

Guida operativa alle schede dell’interfaccia web, con particolare attenzione ai canali di uscita dei dati NMEA0183.

Le schermate provengono da un’installazione reale alimentata con un flusso NMEA di test (posizione fittizia su Udine). I comportamenti descritti sono stati verificati sul campo.

1. Struttura dell’interfaccia

L’applicazione è una pagina unica divisa in due aree.

Interfaccia a riposo

Fig.1 Interfaccia a riposo

Colonna di sinistra — sempre visibile

Blocco Contenuto
Connection Scelta della sorgente (seriale o rete), porta, baud rate, pulsante Connect
Status Rete, IP, stato device, satelliti, qualità del fix, età correzioni RTCM, sorgente, orologio NTP
Position Latitudine, longitudine, altitudine, velocità, direzione, PDOP, accuratezza orizzontale e verticale

Area di destra — otto schede: Console · Map · Satellites · Network · Recording · Settings · Update · About.

Nota

Da sapere: a device non connesso quasi tutti i comandi delle schede appaiono in grigio. Non è un malfunzionamento: si attivano all’atto della connessione.


2. Collegare il ricevitore

Modalità seriale (USB / UART) — quella consigliata

Connessione seriale

Fig.2 Connessione seriale

  1. Selezionare Serial
  2. Scegliere la porta dal menu a tendina — il pulsante ⟳ rilegge l’elenco dei dispositivi
  3. Impostare il baud rate (9600 · 19200 · 38400 · 57600 · 115200 · 230400 · 460800)
  4. Premere Connect

Le porte tipiche sono /dev/ttyACM0 e /dev/ttyACM1 per i ricevitori USB nativi, /dev/ttyUSB0 e /dev/ttyUSB1 per gli adattatori USB-seriale, /dev/ttyAMA0 per la UART del Raspberry Pi.

Modalità rete (TCP / UDP)

Connessione TCP/UDP

Fig.3 Connessione TCP/UDP

  1. Selezionare TCP/UDP
  2. Indicare host e porta della sorgente
  3. Scegliere il protocollo (TCP o UDP)
  4. Premere Connect

Avvertimento

Attenzione: questa modalità ha possibilità ridotte, descritte al capitolo 11: per ritrasmettere o registrare i dati occorre la connessione seriale.


3. Console

Console con flusso NMEA attivo

Fig.4 Console con flusso NMEA attivo

Due riquadri distinti:

  • Connection Messages — il flusso proveniente dal ricevitore, sentence per sentence
  • Network Messages — il traffico NTRIP, quando il client è attivo

Comandi disponibili sopra il primo riquadro:

Comando Effetto
Clear Svuota il riquadro
Auto-scroll Segue automaticamente le righe in arrivo
Raw format Mostra la sentence grezza invece della versione interpretata
Show timestamps Antepone l’orario a ogni riga
Max messages Numero di righe conservate in memoria (500 di default)

Nella schermata la colonna di sinistra riporta un fix RTK Fixed con 12 satelliti, età delle correzioni 1,0 s e accuratezza centimetrica.


4. Mappa

Mappa con posizione corrente

Fig.5 Mappa con posizione corrente

Cartografia OpenStreetMap con il marker della posizione corrente, aggiornato a ogni fix. I due pulsanti in alto a destra controllano il blocco della vista sulla posizione e il cambio di livello cartografico; il pulsante in alto a sinistra ricentra la mappa.


5. Satelliti

Skyplot e rapporto segnale-rumore

Fig.6 Skyplot e rapporto segnale-rumore

Due grafici sincronizzati:

  • Skyplot — posizione dei satelliti nella volta celeste per azimut ed elevazione. I cerchi concentrici sono le linee di elevazione; il centro è lo zenit.
  • Istogramma SNR — rapporto segnale-rumore in dB-Hz per ogni satellite tracciato

Il colore distingue le costellazioni. Le sigle seguono la nomenclatura NMEA: GP = GPS, GL = GLONASS, GA = Galileo, GB = BeiDou, GI = NavIC/IRNSS.


6. Network — NTRIP e server TCP

Scheda Network

Fig.7 Scheda Network

NTRIP Client Configuration

Riceve le correzioni differenziali RTK da un caster.

Campo Descrizione
Profilo Menu dei profili salvati; Save memorizza la configurazione corrente, Delete la rimuove
Host/IP e porta Indirizzo del caster NTRIP (porta 2101 di default)
Mountpoint Punto di montaggio; Search interroga la sourcetable del caster
Username / Password Credenziali, se il caster le richiede
Modalità GGA Invio della posizione al caster — necessario per le reti VRS
Intervallo Cadenza di invio del GGA in secondi
Auto Connect Connette il client NTRIP appena il device si collega

I profili risiedono in backend/ntrip_profiles.json.

TCP Server Configuration

È il canale principale per ritrasmettere i dati ad altri programmi.

Campo Valore
Porta 2948 di default; l’intervallo pubblicato è 2947-2950
Client massimi 2 di default
Auto Start Avvia il server appena il device si collega

Premendo Start il server entra in ascolto:

Server TCP avviato

Fig.8 Server TCP avviato

Ogni client che si collega compare nell’elenco Connected Clients, con il contatore in intestazione che passa a (1/2):

Client collegato al server TCP

Fig.9 Client collegato al server TCP


7. Registrazione

Scheda Recording

Fig.10 Scheda Recording

Start Recording apre un file di testo e vi scrive le sentence NMEA, una per riga. Durante la registrazione il pannello indica il numero di messaggi salvati:

Registrazione in corso

Fig.11 Registrazione in corso

A registrazione conclusa la sessione compare nell’elenco, con dimensione, data e ora:

Elenco delle sessioni registrate

Fig.12 Elenco delle sessioni registrate

I file portano il nome AAAAMMGG_HHMMSS.txt, risiedono nella cartella recordings/ e si scaricano con Download. Auto Record on device connection avvia la registrazione automaticamente a ogni collegamento del ricevitore.


8. Impostazioni

Lingua e sentence NMEA

Impostazioni: lingua e sentence NMEA

Fig.13 Impostazioni: lingua e sentence NMEA

Language — italiano o inglese, si applica con Apply.

NMEA Sentences — determina quali sentence il ricevitore deve emettere:

Sigla Contenuto Sigla Contenuto
GGA Dati del fix GLL Posizione geografica
GSA DOP e satelliti attivi GSV Satelliti in vista
RMC Posizione, velocità, tempo VTG Rotta e velocità
GBS Rilevamento guasti GRS Residui di range
GNS Dati fix multi-costellazione ZDA Data e ora
DTM Datum di riferimento VLW Distanza percorsa

Select All e Deselect All agiscono su tutte le voci insieme; Disable NMEA Sentences interrompe l’emissione.

Questi comandi riconfigurano il ricevitore, non filtrano la visualizzazione. Disattivando GGA la posizione non arriva più: né a schermo, né al server TCP, né alla registrazione.

Formato coordinate e bridge

Impostazioni: formato coordinate e bridge

Fig.14 Impostazioni: formato coordinate e bridge

Coordinate Format — quattro rappresentazioni della posizione:

Formato Esempio
DD — gradi decimali 41.40338°
DMS — gradi, primi, secondi 41°24’12.17”N
XYZ — cartesiane ECEF metri
UTM — Universal Transverse Mercator fuso automatico

Bridge GNSS Configuration — attiva il ponte seriale→TCP (ser2net) sulle porte 3333, 3335 e 3336.

Avvertimento

Esclusione reciproca: il bridge non parte se il device è già collegato dall’applicazione, ed è il motivo per cui il pulsante Start appare in grigio nella schermata. Il bridge accede direttamente alla porta seriale, scavalcando il backend: o l’uno, o l’altro.


9. Aggiornamento e informazioni

Scheda Update

Fig.15 Scheda Update

Update mostra la versione installata e verifica con Check Updates la presenza di versioni più recenti su Docker Hub (marcuzz0/webgnssclient). Il riquadro Update Activity Log riporta l’esito di ogni operazione.

Scheda About

Fig.16 Scheda About

About riporta versione, data di rilascio, autore e licenza (GNU GPL v3.0).


10. Output NMEA0183: come portarlo fuori

Il sistema ritrasmette NMEA0183, non lo genera: inoltra i byte così come arrivano dal ricevitore (forward_to_tcp_clients(raw_data), backend/main.py:573). Se il ricevitore emette NMEA, in uscita si ottiene NMEA0183; se emette UBX o RTCM3, esce quel formato tal quale. Non esiste conversione da UBX a NMEA.

Le quattro vie di uscita

Canale Formato Uso tipico
Server TCP (2947-2950) passthrough grezzo software esterni in rete
Bridge ser2net (3333/3335/3336) grezzo, preceduto da banner accesso diretto alla seriale
File registrati testo, una sentence per riga post-elaborazione
WebSocket ``/ws`` JSON con la sentence in raw_string client su misura

1. Server TCP integrato

Voce Valore
Endpoint POST /api/server/start?port=2948&max_clients=2
Codice backend/main.py:1345
Porte pubblicate 2947-2950 (docker-compose.yml:10)
Bind 0.0.0.0, modalità raw
Client massimi 2 di default, regolabili dall’interfaccia

Endpoint correlati: GET /api/server/status, POST /api/server/stop.

Nota

Nota tecnica. L’inoltro avviene dentro il blocco if parsed_data: (backend/main.py:572): i byte raggiungono i client solo quando il parser produce un messaggio valido. Per NMEA ben formato non cambia nulla, ma dati corrotti o protocolli non riconosciuti non passano.

2. Bridge ser2net

Ponte seriale→TCP diretto, che scavalca il backend (backend/ser2net.conf).

Porta Device Baud
3333 /dev/ttyAMA0 38400
3335 /dev/ttyACM1 115200
3336 /dev/ttyUSB0 115200

Endpoint: POST /api/ser2net/start, POST /api/ser2net/stop, GET /api/ser2net/status.

Due avvertenze: la partenza viene rifiutata se il device è già collegato dall’applicazione (backend/main.py:2367), e all’apertura della connessione viene inviato un banner testuale che alcuni parser NMEA non gradiscono.

3. Registrazione su file

Unico canale che produce NMEA0183 in forma canonica, una sentence per riga (backend/main.py:565). Endpoint: POST /api/recording/start con filtri per tipo di sentence, POST /api/recording/stop, GET /api/recording/status, GET /api/recordings, GET /api/recordings/{filename} per il download. Volume persistente: ./recordings.

4. WebSocket

Ogni messaggio è JSON e contiene la sentence originale nel campo raw_string, insieme a protocol, message_type, parsed e ai dati estratti. Richiede un client dedicato.

Procedura consigliata

  1. Collegare il ricevitore in modalità seriale
  2. Aprire Network → TCP Server Configuration
  3. Verificare porta (2948) e numero di client, quindi premere Start
  4. Puntare il software di destinazione su IP_DELLA_MACCHINA:2948

Verifica rapida da riga di comando:

nc INDIRIZZO_IP 2948

Il flusso atteso:

# Connected to WebGNSS TCP Server
$GNGGA,105324.00,4557.74572736,N,01315.20260980,E,7,25,0.7,51.0352,M,45.0395,M,,*48
$GNGSA,M,3,03,04,06,07,09,11,,,,,,,1.3,0.7,1.1,1*37
$GNRMC,105324.00,A,4557.74572736,N,01315.20260980,E,0.006,203.9,250826,...

Client compatibili senza configurazione aggiuntiva: QGIS, SW Maps, RTKLIB, u-center via TCP, gpsd.

Cosa il sistema non offre

  • Output UDP — il tipo udp esiste solo in ingresso (backend/main.py:137), non come destinazione broadcast
  • Porta seriale virtuale in uscita — nessun pty verso applicazioni locali
  • Conversione UBX → NMEA — nessuna generazione di sentence dai dati interpretati

11. Scelta della sorgente: seriale o rete

La modalità di collegamento del ricevitore non è indifferente rispetto a ciò che il sistema riesce a fare con i dati.

Funzione Sorgente seriale Sorgente TCP/UDP
Visualizzazione a schermo completa limitata
Ritrasmissione via server TCP disponibile non disponibile
Registrazione su file disponibile non disponibile

Nota

Indicazione operativa. Per ritrasmettere i dati ad altri programmi o per registrarli su file occorre collegare il ricevitore in modalità seriale. La modalità TCP/UDP è pensata per la sola consultazione a schermo del flusso in arrivo.


12. Lettura dei campi di stato

Qualità del fix

Il valore riproduce fedelmente l’indicatore di qualità del campo GGA:

Valore Etichetta Significato
0 No Fix nessuna soluzione
1 Standard fix singolo autonomo
2 DGPS correzione differenziale
4 RTK Fixed ambiguità risolte, precisione centimetrica
5 RTK Float ambiguità non risolte, precisione decimetrica
7 Manual posizione immessa manualmente

Nota

Caso ricorrente — perché compare “Manual”. Un ricevitore configurato come stazione base con coordinate fisse (MODE BASE sugli Unicore, TMODE3 = Fixed sugli u-blox) dichiara nel GGA il valore 7, perché la posizione non è calcolata ma immessa dall’operatore. L’indicazione è corretta: lo confermano anche $GNRMC,...,M e $GNGSA,M,3,.... Per leggere Standard occorre riportare il ricevitore in modalità rover.

Altri campi

Campo Significato
Satellites usati nella soluzione / totali in vista
RTCM Age secondi trascorsi dall’ultima correzione ricevuta; oltre i 30 s la soluzione RTK decade
Source protocollo della sorgente in uso
PDOP diluizione della precisione — sotto 2 è una buona geometria satellitare
H Acc / V Acc accuratezza stimata, orizzontale e verticale
Clock orario sincronizzato via NTP

13. Il protocollo NMEA0183

Capitolo di riferimento sul formato dei dati che attraversano il sistema. Tutti gli esempi sono sentence reali catturate da questa installazione.

Anatomia di una sentence

$GNGGA,105324.00,4557.74572736,N,01315.20260980,E,7,25,0.7,51.0352,M,45.0395,M,,*48
│└─┬┘└┬┘ └──────────────────── campi separati da virgola ─────────────────────┘ └┬┘
│  │  └── tipo di messaggio (GGA)                                    checksum ───┘
│  └───── talker: quale costellazione parla (GN = combinata)
└──────── inizio sentence

Regole del formato:

  • ogni sentence comincia con $ e termina con <CR><LF>
  • lunghezza massima 82 caratteri, delimitatori compresi
  • i campi sono separati da virgola e possono essere vuoti: due virgole consecutive significano “dato non disponibile”, non zero
  • il checksum dopo * è lo XOR di tutti i byte compresi tra $ e *, esclusi, scritto in esadecimale a due cifre

Talker: chi parla

I due caratteri dopo il $ dicono da quale costellazione proviene il dato.

Talker Costellazione
GP GPS (Stati Uniti)
GL GLONASS (Russia)
GA Galileo (Unione Europea)
GB BeiDou (Cina)
GI NavIC / IRNSS (India)
GQ QZSS (Giappone)
GN soluzione combinata multi-costellazione

Un ricevitore multi-costellazione emette $GNGGA per la posizione calcolata su tutti i sistemi, ma $GPGSV, $GLGSV, $GAGSV separati per i satelliti di ciascuno.

Le sentence principali, campo per campo

GGA — dati del fix

$GNGGA,105324.00,4557.74572736,N,01315.20260980,E,7,25,0.7,51.0352,M,45.0395,M,,*48
# Valore Significato
1 105324.00 ora UTC, hhmmss.ss
2-3 4557.74572736,N latitudine e emisfero
4-5 01315.20260980,E longitudine e emisfero
6 7 qualità del fix, vedi capitolo 12
7 25 satelliti usati nella soluzione
8 0.7 HDOP
9-10 51.0352,M quota sul geoide, in metri
11-12 45.0395,M separazione geoidale, in metri
13 vuoto età delle correzioni differenziali, in secondi
14 vuoto identificativo della stazione differenziale

Nota

Quota ellissoidica. Il campo 9 è la quota ortometrica, riferita al geoide. Per ottenere quella ellissoidica, richiesta da molti software topografici, si sommano campo 9 e campo 11: 51,0352 + 45,0395 = 96,0747 m.

RMC — il minimo indispensabile

$GNRMC,105324.00,A,4557.74572736,N,01315.20260980,E,0.006,203.9,250826,,,M,S
# Valore Significato
1 105324.00 ora UTC
2 A stato: A valido, V non valido
3-6   latitudine e longitudine, con emisferi
7 0.006 velocità al suolo, in nodi
8 203.9 rotta vera, in gradi
9 250826 data, ggmmaa
10-11 vuoti declinazione magnetica e verso
12 M modalità di posizionamento
13 S stato di navigazione

La modalità al campo 12 usa questo alfabeto: A autonomo, D differenziale, R RTK fixed, F RTK float, E stimato, M immesso manualmente, N non valido.

GSA — geometria e satelliti attivi

$GNGSA,M,3,03,04,06,07,09,11,,,,,,,1.3,0.7,1.1,1*37
# Valore Significato
1 M selezione 2D/3D: A automatica, M manuale
2 3 tipo di fix: 1 assente, 2 bidimensionale, 3 tridimensionale
3-14 03,04,… fino a dodici identificativi di satellite
15 1.3 PDOP
16 0.7 HDOP
17 1.1 VDOP
18 1 sistema: 1 GPS, 2 GLONASS, 3 Galileo, 4 BeiDou

Un ricevitore multi-costellazione emette un GSA per sistema. I tre DOP sono legati fra loro: PDOP² = HDOP² + VDOP², e infatti √(0,7² + 1,1²) = 1,30.

GSV — satelliti in vista

$GPGSV,2,1,08,05,72,145,51,07,58,210,48,09,45,300,45,13,39,085,44*7C

I primi tre campi sono l’intestazione: 2 messaggi in totale, questo è il numero 1, 08 satelliti in vista. Seguono blocchi di quattro valori, uno per satellite:

Valore Significato
05 identificativo del satellite
72 elevazione sull’orizzonte, 0-90 gradi
145 azimut, 0-359 gradi dal nord
51 rapporto segnale-rumore in dB-Hz — vuoto se il satellite è visto ma non tracciato

Ogni messaggio porta al massimo quattro satelliti: per dodici satelliti servono tre GSV. Sono le sentence che alimentano skyplot e istogramma del capitolo 5.

VTG e ZDA

$GNVTG,0.0,T,,M,0.80,N,1.48,K,R*05
$GNZDA,104735.00,25,08,2026,00,00*75

VTG riporta rotta vera (T) e magnetica (M), poi la velocità due volte: in nodi (N) e in chilometri orari (K). ZDA porta ora UTC, giorno, mese, anno e lo scostamento del fuso orario locale in ore e minuti.

La trappola delle coordinate

Il formato NMEA non è in gradi decimali: è ggmm.mmmm, cioè gradi seguiti da primi con la parte decimale. La longitudine usa tre cifre per i gradi, la latitudine due.

4557.74572736  →  45° 57,74572736'  →  45 + 57,74572736 / 60  =  45,962428789°
01315.20260980 →  13° 15,20260980'  →  13 + 15,20260980 / 60  =  13,253376830°

Leggere 4557.7457 come 45,5774 gradi è l’errore più comune nell’interpretazione manuale delle sentence, e sposta la posizione di decine di chilometri.

Quanto occupa il flusso

Misura rilevata su questa installazione, con 25 satelliti tracciati, tutte le sentence attive e cadenza di 1 Hz: circa 2,2 kB al secondo, ovvero 17.560 byte in otto secondi. Su una seriale a 115200 baud, che trasporta circa 11,5 kB/s, resta ampio margine; a 9600 baud (960 byte/s) lo stesso flusso non passa e il ricevitore perde messaggi.

Nota

Regola pratica. Se le sentence arrivano tronche o il checksum non torna, il primo sospetto è il baud rate troppo basso per la quantità di dati richiesta. Il rimedio è alzare il baud rate oppure disattivare le sentence non necessarie dal capitolo 8.

Verificare un checksum a mano

Il checksum è lo XOR di tutti i byte tra $ e *. Verifica da riga di comando:

python3 -c "
from functools import reduce
s = 'GNZDA,104735.00,25,08,2026,00,00'
print(f'{reduce(lambda a,c: a ^ ord(c), s, 0):02X}')"
# 75  →  coincide con *75 della sentence

Riferimenti rapidi

Risorsa Indirizzo
Interfaccia web http://INDIRIZZO:8088
API e documentazione http://INDIRIZZO:8001/docs
Uscita dati TCP INDIRIZZO:2948
Bridge ser2net INDIRIZZO:3333 · :3335 · :3336
docker compose up -d                    # avvio
docker compose logs -f backend          # log del backend
docker compose restart backend          # riavvio dopo modifiche
docker compose down                     # arresto